/*******************************************************************************
 * Copyright (c) 2009-2011 ETCORE Labs. All rights reserved. 
 * 
 * This software is the confidential and proprietary information of ETCORE Labs.
 * You shall not disclose such confidential information and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with ETCORE Labs. 
 * 
 * Support can be obtained from support forums at:  http://www.etcore.com/
 * /
 *******************************************************************************/
package etcore.webapp.grouptalk.common.config;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * ConfigReader is a configuration reader which has utility methods for reading
 * messages and configurations.
 * 
 * @author ETCORE GroupTalk Developers
 * 
 */
public class ConfigReader {

	public static final String LOCAL_MESSAGE_FILE = "/messages.xml";
	public static final String ENGLISH_MESSAGE_FILE = "/emessages.xml";
	public static final String CONFIG_FILE = "/config.properties";
	public static final String LAYOUT_FILE = "/layout.properties";
	public static final String NAME = "name";
	public static final String VALUE = "value";
	public static final String LABEL = "label";
	public static final String PROPERTY = "property";

	public static Document read(InputStream in) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		Document doc = null;
		try {
			DocumentBuilder docBuilder = factory.newDocumentBuilder();

			doc = docBuilder.parse(in);
			// String keyStr = "1234567890vfsvfs";

		} catch (Exception e) {
			e.printStackTrace();
		}

		return doc;
	}

	/**
	 * Read local language messages from the XML file
	 * 
	 * @return message map
	 */
	public static Map<String, Map<String, String>> readMessages() {
		Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();

		InputStream is = null;
		try {
			URL url = ConfigReader.class.getResource(LOCAL_MESSAGE_FILE);
			if (url != null)
				is = url.openStream();
			// is =
			Document doc = read(is);
			if (doc != null) {
				Node commonNode = doc.getElementsByTagName(
						MessageNamespaces.COMMON).item(0);
				NodeList list = commonNode.getChildNodes();

				Map<String, String> commonMap = new HashMap<String, String>();
				if (list != null)
					for (int i = 0; i < list.getLength(); i++) {
						Node node = list.item(i);
						if (node instanceof Element) {
							Element e = (Element) node;
							String name = e.getAttribute(NAME);
							String value = e.getAttribute(VALUE);
							commonMap.put(name, value);
						}

					}
				result.put(MessageNamespaces.COMMON, commonMap);

				NodeList pageList = doc
						.getElementsByTagName(MessageNamespaces.NAMESPACE);

				if (pageList != null) {

					for (int i = 0; i < pageList.getLength(); i++) {
						Node node = pageList.item(i);

						String name = ((Element) node).getAttribute(NAME);
						NodeList labels = node.getChildNodes();

						if (labels != null) {
							Map<String, String> pageMap = new HashMap<String, String>();

							for (int j = 0; j < labels.getLength(); j++) {
								Node lable = labels.item(j);
								if (lable instanceof Element) {
									Element labelElement = (Element) lable;
									String labelName = labelElement
											.getAttribute(NAME);
									String labelValue = labelElement
											.getAttribute(VALUE);
									pageMap.put(labelName, labelValue);
								}
							}

							result.put(name, pageMap);
						}

					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;

	}

	/**
	 * Read English messages from the XML file
	 * 
	 * @return message map
	 */
	public static Map<String, Map<String, String>> readEnglishMessages() {
		Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();

		InputStream is = null;
		try {
			URL url = ConfigReader.class.getResource(ENGLISH_MESSAGE_FILE);
			if (url != null)
				is = url.openStream();
			// is =
			Document doc = read(is);
			if (doc != null) {
				Node commonNode = doc.getElementsByTagName(
						MessageNamespaces.COMMON).item(0);
				NodeList list = commonNode.getChildNodes();

				Map<String, String> commonMap = new HashMap<String, String>();
				if (list != null)
					for (int i = 0; i < list.getLength(); i++) {
						Node node = list.item(i);
						if (node instanceof Element) {
							Element e = (Element) node;
							String name = e.getAttribute(NAME);
							String value = e.getAttribute(VALUE);
							commonMap.put(name, value);
						}

					}
				result.put(MessageNamespaces.COMMON, commonMap);

				NodeList pageList = doc
						.getElementsByTagName(MessageNamespaces.NAMESPACE);

				if (pageList != null) {

					for (int i = 0; i < pageList.getLength(); i++) {
						Node node = pageList.item(i);

						String name = ((Element) node).getAttribute(NAME);
						NodeList labels = node.getChildNodes();

						if (labels != null) {
							Map<String, String> pageMap = new HashMap<String, String>();

							for (int j = 0; j < labels.getLength(); j++) {
								Node lable = labels.item(j);
								if (lable instanceof Element) {
									Element labelElement = (Element) lable;
									String labelName = labelElement
											.getAttribute(NAME);
									String labelValue = labelElement
											.getAttribute(VALUE);
									pageMap.put(labelName, labelValue);
								}
							}

							result.put(name, pageMap);
						}

					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;

	}

	/**
	 * Read configuration
	 * 
	 * @return properties
	 */
	public static Properties readConfig() {
		Properties result = new Properties();
		InputStream is = null;
		try {
			URL url = ConfigReader.class.getResource(CONFIG_FILE);
			if (url != null)
				is = url.openStream();

			result.load(is);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;

	}

	public static void storeConfig(Properties properties) {
		URL url = ConfigReader.class.getResource(CONFIG_FILE);
		if (url != null) {
			try {

				FileOutputStream out = new FileOutputStream(new File(
						url.toURI()));

				properties.store(out, "");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static Properties readLayout() {
		Properties result = new Properties();
		InputStream is = null;
		try {
			URL url = ConfigReader.class.getResource(LAYOUT_FILE);
			if (url != null)
				is = url.openStream();

			result.load(is);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;

	}

	public static void storeLayout(Properties properties) {
		URL url = ConfigReader.class.getResource(LAYOUT_FILE);
		if (url != null) {
			try {

				FileOutputStream out = new FileOutputStream(new File(
						url.toURI()));

				properties.store(out, "");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
